#include "Agent.h"
#include "SteeringBehaviour.h"
#include "AgentGroup.h"
#include "Timer.h"
#include "SteeringOutput.h"
#include "AIManager.h"

namespace Engine
{
	Agent::Agent():m_target(nullptr), m_group(nullptr){}

	void Agent::AddSteeringBehaviour(const WeightedSteeringBehaviour& b, Agent* target)
	{
		auto it = m_steeringBehaviourMap.find(b.first ->GetHash());
		if(it != m_steeringBehaviourMap.end()) return;

		m_steeringBehaviourMap[b.first ->GetHash()] = b;
		b.first ->SetParent(this);
		b.first ->SetTarget(target);

		//m_target = target;
	}

	SteeringBehaviour* Agent::GetSteeringBehaviour(unsigned int hash)
	{
		auto it = m_steeringBehaviourMap.find(hash);
		if(it == m_steeringBehaviourMap.end()) return nullptr;

		return it ->second.first;
	}

	void Agent::RemoveSteeringBehaviour(unsigned int hash)
	{
		auto it = m_steeringBehaviourMap.find(hash);
		if(it == m_steeringBehaviourMap.end()) return;

		delete it ->second.first;
		m_steeringBehaviourMap.erase(it);
	}

	void Agent::Initialize()
	{
		if(m_initialized) return;
		TheAIManager::Instance() ->RegisterAIAgent(this);
		CollidableObject::Initialize();
	}

	void Agent::Release()
	{
		if(!m_initialized) return;
		TheAIManager::Instance() ->UnregisterAIAgent(GetGameObjectID());
		CollidableObject::Release();
	}
		
	void Agent::Update()
	{
		//calculate forces that apply to this update
		SteeringOutput temp;

		for(auto it = m_steeringBehaviourMap.begin(); it != m_steeringBehaviourMap.end(); ++it)
		{
			temp.Reset();

			it ->second.first ->Update(&temp);
			m_steeringOutput.linear += temp.linear * it ->second.second;
			m_steeringOutput.angular += temp.angular * it ->second.second;
		}

		PhysicsObject::Update();
	}

	void Agent::Draw()
	{		
		for(auto it = m_steeringBehaviourMap.begin(); it != m_steeringBehaviourMap.end(); ++it)
		{
			it ->second.first ->Draw();
		}
	}

	Agent::~Agent()
	{
		for(auto it = m_steeringBehaviourMap.begin(); it != m_steeringBehaviourMap.end(); ++it)
			delete it ->second.first;

		Release();

		TheAIManager::Instance() ->UnregisterAIAgent(GetGameObjectID());
	}
}